package com.example.test;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

/**
 * 上传依赖到 Maven 私服
 *
 * https://www.jb51.net/article/152945.htm
 *
 * @author liuzenghui
 * @since 2017/7/31.
 */
public class Deploy {
    public static final String BASE_CMD = "cmd /c mvn " +
            "-s C:\\Users\\liugb\\.m3\\settings.xml ^\n" +
            "deploy:deploy-file ^\n" +
            "-DgroupId=%s ^\n" +
            "-DartifactId=%s ^\n" +
            "-Dversion=%s ^\n" +
            "-Dpackaging=jar ^\n" +
            "-Dfile=%s ^\n" +
            "-DrepositoryId=nexus ^\n" +
            "-Dusername=admin ^\n" +
            "-Dpassword=123456 ^\n" +
            "-Durl=http://192.168.38.128:8081/repository/%s/";

    public static final String BASE_CMD_POM = "cmd /c mvn " +
            "-s C:\\Users\\liugb\\.m3\\settings.xml ^\n" +
            "deploy:deploy-file ^\n" +
            "-DgroupId=%s ^\n" +
            "-DartifactId=%s ^\n" +
            "-Dversion=%s ^\n" +
            "-Dpackaging=pom ^\n" +
            "-Dfile=%s ^\n" +
            "-DrepositoryId=nexus ^\n" +
            "-Dusername=admin ^\n" +
            "-Dpassword=123456 ^\n" +
            "-Durl=http://192.168.38.128:8081/repository/%s/";

    public static final Pattern DATE_PATTERN = Pattern.compile("-[\\d]{8}\\.[\\d]{6}-");

    public static final Runtime CMD = Runtime.getRuntime();

    public static final Writer ERROR;

    public static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(10);

    static {
        Writer err = null;
        try {
            err = new OutputStreamWriter(new FileOutputStream("deploy-error.log"), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
        ERROR = err;
    }

    public static void main(String[] args) {
        var files = getFilesRecursively(new File("E:\\jar\\das"));
        //忽略日期快照版本，如 xxx-mySql-2.2.6-20170714.095105-1.jar
        for (File file : files) {
            String name = file.getName();
            if (DATE_PATTERN.matcher(name).find()) {
                continue;
            }
            if (name.endsWith("-sources.jar")) {
                continue;
            }
            if (name.endsWith(".jar")) {
                deploy(file);
                fn.add(file.getName());
            }
            if (name.endsWith(".pom")) {
                deployPom(file);
                fn.add(file.getName());
            }
        }

        EXECUTOR_SERVICE.shutdown();
        try {
            ERROR.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void deployPom(final File pom) {
        EXECUTOR_SERVICE.execute(new Runnable() {
            @Override
            public void run() {
                String DgroupId = "com.das";
                if (pom.getPath().contains("libcore")) {
                    DgroupId = "com.das.libcore";
                }

                String DartifactId = extractName(pom.getName());
                String Dversion = extractVersion(pom.getName());
                var rep = "maven-releases";
                if (Dversion.contains("SNAPSHOT")) {
                    rep = "maven-snapshots";
                }
                Dversion = Dversion.replace(".pom", "");
                String Dfile = pom.getPath();
                var cmd = String.format(BASE_CMD_POM, DgroupId, DartifactId, Dversion, Dfile, rep);
                System.out.println(cmd);
                try {
                    final Process proc = CMD.exec(cmd.toString(), null, pom.getParentFile());
                    InputStream inputStream = proc.getInputStream();
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                    BufferedReader reader = new BufferedReader(inputStreamReader);
                    String line;
                    StringBuffer logBuffer = new StringBuffer();
                    logBuffer.append("\n\n\n==================================\n");
                    while ((line = reader.readLine()) != null) {
                        if (line.startsWith("[INFO]") || line.startsWith("Upload")) {
                            logBuffer.append(Thread.currentThread().getName() + " : " + line + "\n");
                        }
                    }
                    //System.out.println(logBuffer);
                    int result = proc.waitFor();
                    if (result != 0) {
                        error("上传失败：" + pom.getAbsolutePath());
                    }
                } catch (IOException e) {
                    error("上传失败：" + pom.getAbsolutePath());
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    error("上传失败：" + pom.getAbsolutePath());
                    e.printStackTrace();
                }
            }
        });
    }

    public static void error(String error) {
        try {
            System.err.println(error);
            ERROR.write(error + "\n");
            ERROR.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static boolean checkArgs(String[] args) {
        if (args.length != 1) {
            System.out.println("用法如： java -jar Deploy D:\\some\\path\\");
            return false;
        }
        File file = new File(args[0]);
        if (!file.exists()) {
            System.out.println(args[0] + " 目录不存在!");
            return false;
        }
        if (!file.isDirectory()) {
            System.out.println("必须指定为目录!");
            return false;
        }
        return true;
    }

    private static List<String> fn = new ArrayList<>();

    public static void deploy(File[] files) {
        if (files.length == 0) {
            //ignore
        } else if (files[0].isDirectory()) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deploy(file.listFiles());
                }
            }
        } else if (files[0].isFile()) {
            //忽略日期快照版本，如 xxx-mySql-2.2.6-20170714.095105-1.jar
            for (File file : files) {
                String name = file.getName();
                if (DATE_PATTERN.matcher(name).find()) {
                    continue;
                }
                if (name.endsWith("-sources.jar")) {
                    continue;
                }
                if (name.endsWith(".jar")) {
                    fn.add(file.getName());
                    deploy(file);

                }
            }
        }
    }

    public static List<File> getFilesRecursively(File directory) {
        List<File> fileList = new ArrayList<>();
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    fileList.addAll(getFilesRecursively(file));
                } else {
                    fileList.add(file);
                }
            }
        }
        return fileList;
    }


    private static String extractVersion(String fileName) {
        // 使用正则表达式分割文件名
        String[] parts = fileName.split("-");

        // 找到包含版本号的部分
        for (String part : parts) {
            if (part.contains(".")) {
                if (fileName.contains("-SNAPSHOT")) {
                    return part + "-SNAPSHOT";
                } else {
                    return part;
                }
            }
        }

        // 如果没有找到版本号,返回空字符串
        return "";
    }

    private static boolean validate(String fileName) {
        String[] parts = fileName.split("-");
        for (int i = 0; i < parts.length; i++) {
            var part = parts[i];
            if (part.contains(".")) {
                if (i + 1 >= parts.length)
                    return false;
                if (parts[i + 1].contains("SNAPSHOT") || parts[i + 1].contains(".jar"))
                    return true;
                break;
            }
        }

        return false;
    }

    private static String extractName(String fileName) {
        String[] parts = fileName.split("-");
        StringBuilder sb = new StringBuilder();
        for (String part : parts) {
            if (part.contains(".")) {
                break;
            }
            sb.append(part);
            sb.append("-");
        }
        if (sb.length() > 0) {
            return sb.substring(0, sb.length() - 1);
        }
        return "";
    }

    public static void deploy(final File pom) {
        EXECUTOR_SERVICE.execute(new Runnable() {
            @Override
            public void run() {
                String DgroupId = "com.das";
                if (pom.getPath().contains("libcore")) {
                    DgroupId = "com.das.libcore";
                }
                String DartifactId = extractName(pom.getName());
                String Dversion = extractVersion(pom.getName());
                var rep = "maven-releases";
                if (Dversion.contains("SNAPSHOT")) {
                    rep = "maven-snapshots";
                }
                Dversion = Dversion.replace(".jar", "");
                String Dfile = pom.getPath();
                var cmd = String.format(BASE_CMD, DgroupId, DartifactId, Dversion, Dfile, rep);

                System.out.println(cmd);

                try {
                    final Process proc = CMD.exec(cmd.toString(), null, pom.getParentFile());
                    InputStream inputStream = proc.getInputStream();
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                    BufferedReader reader = new BufferedReader(inputStreamReader);
                    String line;
                    StringBuffer logBuffer = new StringBuffer();
                    logBuffer.append("\n\n\n=======================================\n");
                    while ((line = reader.readLine()) != null) {
                        if (line.startsWith("[INFO]") || line.startsWith("Upload")) {
                            logBuffer.append(Thread.currentThread().getName() + " : " + line + "\n");
                        }
                    }
                    //System.out.println(logBuffer);
                    int result = proc.waitFor();
                    if (result != 0) {
                        error("上传失败：" + pom.getAbsolutePath());
                    }
                } catch (IOException e) {
                    error("上传失败：" + pom.getAbsolutePath());
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    error("上传失败：" + pom.getAbsolutePath());
                    e.printStackTrace();
                }
            }
        });
    }
}